#include "stdafx.h"
#include "convert.h"
#include "sorting.h"
;using namespace std;

#define MAX_FILE_SIZE 2*1024*1024*1024

void DisplayError(TCHAR* pszAPI, DWORD dwError)
{
    LPVOID lpvMessageBuffer;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                  FORMAT_MESSAGE_FROM_SYSTEM |
                  FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL, dwError,
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  (LPTSTR)&lpvMessageBuffer, 0, NULL);

    //... now display this string
    _tprintf(TEXT("ERROR: API        = %s\n"), pszAPI);
    _tprintf(TEXT("       error code = %d\n"), dwError);
    _tprintf(TEXT("       message    = %s\n"), lpvMessageBuffer);

    // Free the buffer allocated by the system
    LocalFree(lpvMessageBuffer);

    ExitProcess(GetLastError());
}


int _tmain(int argc, char *argv[])
{
	/*if(argc < 2)
	{
		cout<<"Not enough files!";
		return 0;
	}*/

	TCHAR* inputFile = _TEXT("in.txt");
	TCHAR* outputFile = _TEXT("out.txt");
	
	HANDLE InputHandle;
	
	InputHandle = CreateFile((inputFile),
		GENERIC_READ|GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_SHARE_READ,
		NULL
	);
	
	if (InputHandle == INVALID_HANDLE_VALUE)
	{
        DisplayError(TEXT("CreateInputFile"), GetLastError());
		getchar();
		return 1;
	}

	LPDWORD lpFileSizeHigh = NULL;
	DWORD FileSize;
	FileSize = GetFileSize( 
			  InputHandle, 
			  lpFileSizeHigh
	);
	
	if(FileSize > MAX_FILE_SIZE)//we don't check files more that 2 Gb
	{
		cout<<"Input file is too big! Must be less than 2Gb\n";
		getchar();
		return 1;
	}
	
	HANDLE InputMappHandle;
	
 
	InputMappHandle = CreateFileMapping(
		InputHandle,
		NULL,
		PAGE_READONLY,
		0,
		0,
		NULL
	);
	
	if (InputMappHandle == INVALID_HANDLE_VALUE)
	{
	    DisplayError(TEXT("CreateFileInputMapping"), GetLastError());
		CloseHandle(InputHandle);
		return 1;
	}
	
	
	LPCTSTR buf;

	buf = (LPTSTR)MapViewOfFile(
		InputMappHandle,
		FILE_MAP_READ,
		0, 
		0,
		0
	);
	
	if (buf == NULL)
	{
		_tprintf(TEXT("Input: Could not map view of file (%d).\n"),
             GetLastError());

      CloseHandle(InputMappHandle);
	  CloseHandle(InputHandle);
      return 2;
	}
	convert* item = new convert(FileSize);
	
	CopyMemory(item->data,(PVOID)buf, FileSize);	
	cout<<"copied\n";
	UnmapViewOfFile(buf);
	CloseHandle(InputMappHandle);
	CloseHandle(InputHandle);


	sorting vec;
	int result = item->DoConvert(&vec.arr);
	
	cout<<"Doconverted\n";
	
	if(result < 0) 
	{
		vec.~sorting();
		item->~convert();
		return -1;
	}
	
	vec.DoSort();
	cout<<"Sorted\n";
	
	long unsigned int sizeOutput = item->DoDeconvert(&vec.arr);

	vec.~sorting();
	cout<<"Outstart\n";
	HANDLE OutputHandle;
	
	OutputHandle = CreateFile((outputFile),
		GENERIC_WRITE|GENERIC_READ,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		CREATE_ALWAYS,
		NULL,
		NULL
	);
	
	if (OutputHandle == INVALID_HANDLE_VALUE)
	{
        DisplayError(TEXT("CreateOuputFile"), GetLastError());
		CloseHandle(OutputHandle);
		item->~convert();
		return 1;
	}

	HANDLE OutputMappHandle;
	
	OutputMappHandle = CreateFileMapping(
		OutputHandle,
		NULL,
		PAGE_READWRITE,
		0,
		FileSize,
		NULL
	);
	
	if (OutputMappHandle == INVALID_HANDLE_VALUE)
	{
		DisplayError(TEXT("CreateFileOutputMapping"), GetLastError());
		CloseHandle(OutputHandle);
		item->~convert();
		return 1;
	}

	buf = (LPTSTR)MapViewOfFile(
		OutputMappHandle,
		FILE_MAP_WRITE,
		0,
		0,
		NULL
	);
	
	if (buf == NULL)
	{
		_tprintf(TEXT("Output: Could not map view of file (%d).\n"),
             GetLastError());

       CloseHandle(OutputMappHandle);
	   CloseHandle(OutputHandle);
	   item->~convert();
      return 2;
	}
	cout<<"before cpy mem\n";
	CopyMemory((PVOID)buf,item->data, sizeOutput);	
	cout<<"before destruct\n";
	item->~convert();
	cout<<"after destr\n";
	UnmapViewOfFile(buf);
	
	CloseHandle(OutputMappHandle);
	CloseHandle(OutputHandle);
	return 0;
}